﻿using AuditSample.Model;
using Microsoft.Activities.Extensions.Tracking;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;
using System.Windows.Forms;

namespace AuditSample
{
    public partial class MainForm : Form
    {
        WorkFlowService wfService = null;
        AutoResetEvent syncEvent = new AutoResetEvent(false);
        public MainForm()
        {
            InitializeComponent();
            this.Load += MainForm_Load;           
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            this.labelState.Text = string.Empty;

            LoadInstances();

            wfService = new WorkFlowService(null, syncEvent);
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            if (wfService.IsLoaded)
                wfService.Unload();
            syncEvent.Reset();

            //using (TransactionScope ts = new TransactionScope())
            //{
                wfService = new WorkFlowService(null, syncEvent);
                wfService.New();
                
                wfService.Run();
                syncEvent.WaitOne();
              
                using (Model1 dbContext = new Model1())
                {
                   
                    WorkFlowInstance instance = new WorkFlowInstance();
                    instance.Title = txtTitle.Text;
                    instance.BusinessId = txtBusinessId.Text;
                    instance.BussinessUrl = txtBusinessUrl.Text;
                    instance.Drafter = txtDrafter.Text;
                    instance.Id = wfService.Id.ToString();
                    instance.IsCompleted = false;
                    instance.IsCancelled = false;
                    instance.Type = wfService.Type;
                    //workflowInstance.State = StateTracker.CurrentState;
                    instance.AddedBy = "1";
                    instance.UpdatedBy = "1";
                    instance.AddedDate = DateTime.Now;
                    instance.UpdatedDate = DateTime.Now;
                    if (wfService.StateTracking.State != null)
                    {
                        instance.AuditRole = wfService.StateTracking.State.AuditRole;
                        instance.Auditer = wfService.StateTracking.State.Auditer;
                        instance.State = wfService.StateTracking.State.State;
                        instance.UpdatedDate = wfService.StateTracking.State.UpdatedDate;
                        instance.RecordNumber = wfService.StateTracking.State.RecordNumber;
                    }
                   
                    dbContext.WorkFlowInstances.Add(instance);
                    dbContext.SaveChanges();
                }


                this.listBoxInstances.Items.Add(wfService);

                txtTitle.Clear();
                txtBusinessId.Clear();
                txtBusinessUrl.Clear();
                txtDrafter.Clear();

                UpdateState();

        //    ts.Complete();
        //}


    }

        void LoadInstances()
        {
            var instances = StateMachineStateTracker.LoadInstances(
               WorkFlowService.Workflow1Definition, WorkFlowService.ConnectionString);

            if (instances != null)
            {
                foreach (var stateMachineStateTracker in instances)
                {
                    //Debug.Assert(this.workFlows != null, "this.Workflows  is null");
                    //this.workFlows.Add(new WorkFlowService(stateMachineStateTracker));
                    WorkFlowService instance = new WorkFlowService(stateMachineStateTracker, syncEvent);
                    this.listBoxInstances.Items.Add(instance);
                }
            }
            this.listBoxInstances.DisplayMember = "Id";
        }

        void UpdateState()
        {
            if (wfService.StateTracker != null)
            {
                this.labelState.Text = wfService.StateTracker.CurrentState;
            }
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (wfService.IsLoaded)
                wfService.Unload();
            if (this.listBoxInstances.SelectedIndex < 0) return;
            wfService= (WorkFlowService)this.listBoxInstances.SelectedItem;
            wfService.Load();
            //wfService.Run();
            this.UpdateState();
        }

        private void btnAudit_Click(object sender, EventArgs e)
        {
            syncEvent.Reset();
            //using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
            //{
                var auditProcess = new AuditProcess();
                auditProcess.CurrentUser = this.cbxAuditerList.Text;
                auditProcess.AuditFlag = this.radioYes.Checked ? "1" : "0";
                auditProcess.Comment = this.txtComment.Text;
                wfService.Host.ResumeBookmark(wfService.StateTracker.CurrentState, auditProcess);
                syncEvent.WaitOne();

                using(Model1 dbContext = new Model1())
                {
                    if (wfService.HistoryTracking.Histotry != null)
                    {
                        var historyDTO = wfService.HistoryTracking.Histotry;
                        var instance = dbContext.WorkFlowInstances.FirstOrDefault(x => x.Id.Equals(historyDTO.InstanceId, StringComparison.InvariantCultureIgnoreCase));
                        if (instance == null) return;
                        WorkFlowHistory history = new WorkFlowHistory();
                        history.Id = historyDTO.Id;
                        history.InstanceId = historyDTO.InstanceId;
                        history.RecordNumber = historyDTO.RecordNumber;
                        history.State = historyDTO.State;
                        history.Action = historyDTO.Action;
                        history.Auditer = historyDTO.Auditer;
                        history.Comment = historyDTO.Comment;
                        history.StartDate = instance.UpdatedDate;
                        history.EndDate = historyDTO.EndDate;
                        dbContext.WorkFlowHistories.Add(history);

                        if (wfService.StateTracking.State != null)
                        {
                            instance.AuditRole = wfService.StateTracking.State.AuditRole;
                            instance.Auditer = wfService.StateTracking.State.Auditer;
                            instance.State = wfService.StateTracking.State.State;
                            instance.UpdatedDate = wfService.StateTracking.State.UpdatedDate;
                            instance.RecordNumber = wfService.StateTracking.State.RecordNumber;
                        }
                    }
                    dbContext.SaveChanges();                  
                }

                this.UpdateState();


                // Method call that interacts with the instance store.
            //    ts.Complete();
            //}

        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            syncEvent.Reset();

            //using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
            //{
                this.wfService.Host.Cancel();
                syncEvent.WaitOne();
                using (Model1 dbContext = new Model1())
                {
                    var instance = dbContext.WorkFlowInstances.FirstOrDefault(x => x.Id.Equals(this.wfService.Host.Id.ToString(), StringComparison.InvariantCultureIgnoreCase));
                    instance.IsCancelled = true;
                    dbContext.SaveChanges();
                }
            //    ts.Complete();
            //}
        }
    }
}
